package com.hsbc.dev.teamo4.sms.common.utils.data;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

/**
 * @author:Cady
 * @version: 将对应的List对象构建为一棵树的工具类
 * @Project: permission_manage
 * @Package: com.hsbc.dev.teamo4.sms.sm.util
 * @Description:
 * @Date date: 2018-07-26
 */
public class TreeUtil<T> {
    /**
     * List数据
     */
    private List<T> allValue;
    /**
     * 表示在树中所属层次的类变量名称
     */
    private String levelField;
    /**
     * 父节点与子节点向关联的类变量名称
     */
    private String connectField;
    /**
     * 子节点中表示父节点的类变量名称
     */
    private String parentField;
    /**
     * 构建成的树的根节点
     */
    private TreeNode<T> root;


    public TreeUtil() {
        root = new TreeNode<>();
    }

    public TreeUtil(List<T> allValue, String levelField, String connectField, String parentField) {
        this();
        this.allValue = allValue;
        this.levelField = levelField;
        this.connectField = connectField;
        this.parentField = parentField;
    }

    public List<T> getAllValue() {
        return allValue;
    }

    public String getLevelField() {
        return levelField;
    }

    public String getConnectField() {
        return connectField;
    }

    public String getParentField() {
        return parentField;
    }

    public void setAllValue(List<T> allValue) {
        this.allValue = allValue;
    }

    public void setLevelField(String levelField) {
        this.levelField = levelField;
    }

    public void setConnectField(String connectField) {
        this.connectField = connectField;
    }

    public void setParentField(String parentField) {
        this.parentField = parentField;
    }

    public void setRoot(TreeNode<T> root) {
        this.root = root;
    }

    public TreeNode<T> getRoot() {
        return root;
    }

    /**
     * @Description 对list进行排序，使用CompareUtil对象，通过level升序排序
     * @Date: 16:53 2018-07-26
     * @Param
     * @return void
     */
    public void sort(){
        CompareUtil<T> compareUtil = new CompareUtil<>(levelField,0);
        Collections.sort(allValue,compareUtil);
    }

    /**
     * @Description 找出parent的子类，并添加到parent的sonNotes中，递归执行
     * @Date: 16:55 2018-07-26
     * @Param parent
     * @Param index
     * @return void
     */
    private void findSons(TreeNode<T> parent, int index) {
        try {
            Field fieldP = parent.getValue().getClass().getDeclaredField(connectField);
            fieldP.setAccessible(true);
            for (int i=index;i<allValue.size();i++) {
                Field field = allValue.get(i).getClass().getDeclaredField(parentField);
                field.setAccessible(true);
                if(field.get(allValue.get(i))!=null&&field.get(allValue.get(i)).equals(fieldP.get(parent.getValue()))) {
                    TreeNode<T> sonNote = new TreeNode<>(allValue.get(i));
                    parent.addSubNote(sonNote);
                    allValue.remove(i);
                    findSons(sonNote,i);
                    i--;
                }
            }
        } catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description 对外接口，完成树的构建，调用findSons完成。
     * @Date: 16:56 2018-07-26
     * @Param
     * @return com.hsbc.dev.teamo4.sms.sm.util.TreeNode<T>
     */
    public TreeNode<T> getTree(){
        sort();
        for (int i=0;i<allValue.size();i++){
            try {
                Field field = allValue.get(i).getClass().getDeclaredField(levelField);
                field.setAccessible(true);
                if ((Integer)field.get(allValue.get(i)) == 0) {
                    TreeNode<T> newNode = new TreeNode<>(allValue.get(i));
                    root.addSubNote(newNode);
                    allValue.remove(0);
                    findSons(newNode, i);
                    i--;
                }
                return root;
            } catch (IllegalAccessException | NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        return root;
    }

    /**
     * @Description 对树模型进行缩进打印
     * @Date: 16:57 2018-07-26
     * @Param
     * @return void
     */
    public void printTree(){
        TreeNode<T> node =root;
        String formatStr="";
        printTree2(node,formatStr);
    }

    /**
     * @Description 递归实现树的打印
     * @Date: 16:58 2018-07-26
     * @Param node
     * @Param formarStr
     * @return void
     */
    private void printTree2(TreeNode<T> node, String formarStr){
        System.out.println(formarStr+node.getValue());
        HashSet<TreeNode> sons=node.getSubNotes();
        for(TreeNode<T> son:sons){
            printTree2(son,formarStr+"\t");
        }
    }

    /**
     * @Description 对外提供静态打印接口
     * @Date: 15:35 2018-07-27
     * @Param node
     * @Param formarStr
     * @return void
     */
    public static void printT(TreeNode node, String formarStr){
        System.out.println(formarStr+node.getValue());
        HashSet<TreeNode> sons=node.getSubNotes();
        for(TreeNode son:sons){
            printT(son,formarStr+"\t");
        }
    }
}


